package com.example.jikeprofiledemo

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.view.ViewGroup
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.coordinatorlayout.widget.CoordinatorLayout.Behavior
import androidx.core.view.ViewCompat

class HeaderScrollBehavior : Behavior<View> {

    private val TAG = "HeaderScrollBehavior"


    private lateinit var containerView: View
    private var containerViewId: Int = 0

    private lateinit var profileBarView: View
    private var profileBarViewId: Int = 0

    private lateinit var profileView: View
    private var profileViewId: Int = 0

    private lateinit var avatarView: View
    private var avatarViewId: Int = 0

    private lateinit var usernameView: View
    private var usernameViewId: Int = 0

    private lateinit var profileSocialView: View
    private var profileSocialViewId: Int = 0

    private lateinit var genderView: View
    private var genderViewId: Int = 0

    private lateinit var hsSomeView: View
    private var hsSomeViewId: Int = 0

    private lateinit var tabLayoutView: View
    private var tabLayoutViewId: Int = 0

    private lateinit var viewPager: View
    private var viewPagerId: Int = 0

    private lateinit var refreshIndicator: JikeRefreshIndicator
    private var refreshIndcatorViewId: Int = 0

    private var headerMargin = 24.dp

    private var animating = false

    lateinit var targetView: View

    private var dragged = false

    private val animateListener = object : AnimatorListenerAdapter() {
        override fun onAnimationStart(animation: Animator?) {
            super.onAnimationStart(animation)
            animating = true
        }

        override fun onAnimationEnd(animation: Animator?) {
            super.onAnimationEnd(animation)
            animating = false
        }
    }

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {

        val typeArray = context.obtainStyledAttributes(attrs, R.styleable.HeaderScrollBehavior)

        containerViewId = typeArray.getResourceId(R.styleable.HeaderScrollBehavior_container, 0)
        profileBarViewId = typeArray.getResourceId(R.styleable.HeaderScrollBehavior_profile_bar, 0)
        profileViewId = typeArray.getResourceId(R.styleable.HeaderScrollBehavior_profile, 0)
        avatarViewId = typeArray.getResourceId(R.styleable.HeaderScrollBehavior_avatar, 0)
        profileSocialViewId =
            typeArray.getResourceId(R.styleable.HeaderScrollBehavior_profile_social, 0)
        genderViewId = typeArray.getResourceId(R.styleable.HeaderScrollBehavior_gender, 0)
        usernameViewId = typeArray.getResourceId(R.styleable.HeaderScrollBehavior_username, 0)
        hsSomeViewId = typeArray.getResourceId(R.styleable.HeaderScrollBehavior_horizontal_layout, 0)
        tabLayoutViewId = typeArray.getResourceId(R.styleable.HeaderScrollBehavior_tablayout, 0)
        viewPagerId = typeArray.getResourceId(R.styleable.HeaderScrollBehavior_viewpager, 0)
        refreshIndcatorViewId = typeArray.getResourceId(R.styleable.HeaderScrollBehavior_refresh_indicator, 0)
        typeArray.recycle()
    }

    override fun onMeasureChild(
        parent: CoordinatorLayout,
        child: View,
        parentWidthMeasureSpec: Int,
        widthUsed: Int,
        parentHeightMeasureSpec: Int,
        heightUsed: Int
    ): Boolean {

        targetView = child
        containerView = parent.findViewById(containerViewId)
        profileBarView = parent.findViewById(profileBarViewId)
        profileView = parent.findViewById(profileViewId)
        avatarView = parent.findViewById(avatarViewId)
        profileSocialView = parent.findViewById(profileSocialViewId)
        genderView = parent.findViewById(genderViewId)
        usernameView = parent.findViewById(usernameViewId)
        hsSomeView = parent.findViewById(hsSomeViewId)
        tabLayoutView = parent.findViewById(tabLayoutViewId)
        viewPager = parent.findViewById(viewPagerId)

        return super.onMeasureChild(
            parent,
            child,
            parentWidthMeasureSpec,
            widthUsed,
            parentHeightMeasureSpec,
            heightUsed
        )
    }

    override fun onLayoutChild(parent: CoordinatorLayout, child: View, layoutDirection: Int): Boolean {
        containerHeight = containerView.measuredHeight
        return super.onLayoutChild(parent, child, layoutDirection)
    }


    override fun onStartNestedScroll(
        coordinatorLayout: CoordinatorLayout,
        child: View,
        directTargetChild: View,
        target: View,
        axes: Int,
        type: Int
    ) = axes and ViewCompat.SCROLL_AXIS_VERTICAL != 0


    override fun onNestedPreScroll(
        coordinatorLayout: CoordinatorLayout,
        child: View,
        target: View,
        dx: Int,
        dy: Int,
        consumed: IntArray,
        type: Int
    ) {
        preScroll(child, dy, consumed)
    }

    var overPullDelta = 0
    private var containerHeight = 0

    private fun setHeight(view: View, height: Int) {
        Log.i(TAG, "setHeight: $containerHeight  ${containerView.height}  $height")
        val layoutParams = view.layoutParams as ViewGroup.LayoutParams
        layoutParams.height = height
        view.layoutParams = layoutParams
    }

    private fun preScroll(child: View, dy: Int, consumed: IntArray) {

        val upBoundary = -hsSomeView.top + profileBarView.bottom
        var allowOffsetContent = true

        //不能往下拉
        if (child.top - dy >= 0) {
            ViewCompat.offsetTopAndBottom(child, -child.top)
            //继续下拉，放大背景图

            profileBarView.translationY = (-profileBarView.top + headerMargin).toFloat()
            return
        } else if (child.top - dy <= upBoundary) { //Parent 不能继续上滑，此时处理 HorizontalScrollView

            ViewCompat.offsetTopAndBottom(child, upBoundary - child.top)

            //保持 头部不动
            profileBarView.translationY = (-child.top).toFloat()

            //让HorizontalScrollView 上移
            if (hsSomeView.translationY - dy <= -hsSomeView.height) {
                consumed[1] = 0
                hsSomeView.translationY = (-hsSomeView.height).toFloat()

            } else {
                hsSomeView.translationY = hsSomeView.translationY - dy
                tabLayoutView.translationY = hsSomeView.translationY
                viewPager.translationY = hsSomeView.translationY
                consumed[1] = dy

                if (profileView.alpha <= 0f && animating.not())
                    profileView.animate()
                        .setListener(animateListener)
                        .alpha(1f)
                        .setDuration(150)
                        .start()
                return
            }
        }

        //如果 HorizontalScrollView 也不能上移了，交给子 View 处理
        if (hsSomeView.translationY <= -hsSomeView.height && dy > 0) {
            consumed[1] = 0
            return
        }

        //如果HorizontalScrollView 此时可以下移，先消费所有的距离
        if (hsSomeView.translationY < 0f && dy < 0) {

            if (hsSomeView.translationY - dy >= 0) {

                //此时可以隐藏 profileBar
                if (profileView.alpha >= 1f && animating.not())
                    profileView.animate()
                        .setListener(animateListener)
                        .alpha(0f)
                        .setDuration(150)
                        .start()

                consumed[1] = hsSomeView.translationY.toInt()
                hsSomeView.translationY = 0f
                tabLayoutView.translationY = 0f
                viewPager.translationY = 0f
                return
            } else {
                hsSomeView.translationY = hsSomeView.translationY - dy
                tabLayoutView.translationY = hsSomeView.translationY
                viewPager.translationY = hsSomeView.translationY
                consumed[1] = dy
                allowOffsetContent = false
            }
        }

        /*正常范围内平移内容、改变响应 view 的透明度*/

        arrayOf(avatarView, usernameView, profileSocialView, genderView)
            .forEach {
                val offset = -child.top - (it.top - profileBarView.bottom)
                it.alpha = 1f - Math.max(0f, offset.toFloat() / Math.min(profileBarView.height, it.height))
            }

        //移动内容
        if (allowOffsetContent)
            ViewCompat.offsetTopAndBottom(child, -dy)

        //保持头部不动
        keepProfileStill()

        consumed[1] = dy
    }

    private fun keepProfileStill() {
        profileBarView.translationY = (-targetView.top).toFloat()
    }


    override fun onStopNestedScroll(coordinatorLayout: CoordinatorLayout, child: View, target: View, type: Int) {
        super.onStopNestedScroll(coordinatorLayout, child, target, type)
        if (dragged) {
            //触发刷新
        }
    }

    /**
     * 刷新完成
     */
    fun onRefreshComplete() {
        dragged = false
    }

    override fun onNestedFling(
        coordinatorLayout: CoordinatorLayout,
        child: View,
        target: View,
        velocityX: Float,
        velocityY: Float,
        consumed: Boolean
    ): Boolean {
        Log.i(TAG, "onNestedFling: $velocityY")
        return super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed)
    }

    override fun onNestedPreFling(
        coordinatorLayout: CoordinatorLayout,
        child: View,
        target: View,
        velocityX: Float,
        velocityY: Float
    ): Boolean {

        Log.i(TAG, "onNestedPreFling: $velocityY")
        return super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY)
    }

}